package com.linkallcloud.core.exception;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import javax.validation.UnexpectedTypeException;

import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

import com.linkallcloud.core.dto.Result;
import com.linkallcloud.core.face.message.response.ErrorFaceResponse;
import com.linkallcloud.core.lang.Strings;
import com.linkallcloud.deapi.DeApiException;

public class Exceptions {

    public static final String CODE_SUCCESS = "0";// 成功

    public static final String CODE_ERROR_UNKNOW = "9001";// 未知错误
    public static final String CODE_ERROR_PARAMETER = "9002";// 参数错误

    public static final String CODE_ERROR_AUTH_ACCOUNT = "9003";// 账号验证失败
    public static final String CODE_ERROR_AUTH_PERMISSION = "9004";// 无权限

    public static final String CODE_ERROR_DB = "9005";// 数据库异常
    public static final String CODE_ERROR_CACHE = "9006";// 缓存异常
    public static final String CODE_ERROR_FILE = "9007";// 文件错误
    public static final String CODE_ERROR_IMAGE = "9008";// 图片错误

    public static final String CODE_ERROR_DELETE = "9010";// DEL错误
    public static final String CODE_ERROR_ADD = "9011";// 新增错误
    public static final String CODE_ERROR_UPDATE = "9012";// 更新错误
    public static final String CODE_ERROR_SEARCH = "9013";// 查询错误
    public static final String CODE_ERROR_SYNC = "9014";// 同步错误

    public static final String CODE_ERROR_TIMEOUT = "9020";// 超时错误
    public static final String CODE_ERROR_SESSION_TIMEOUT = "9021";// 会话超时错误

    public static Result<Object> makeErrorResult(Throwable t) {
        if (t != null) {
            if (t instanceof BaseException) {
                BaseException be = (BaseException) t;
                return makeErrorResult(be.getCode(), be.getMessage());
            } else if (t instanceof BaseRuntimeException) {
                BaseRuntimeException be = (BaseRuntimeException) t;
                return makeErrorResult(be.getCode(), be.getMessage());
            } else if (t instanceof DeApiException) {
                DeApiException be = (DeApiException) t;
                return makeErrorResult(be.getCode(), be.getMessage());
            } else if (t instanceof MaxUploadSizeExceededException) {
                return makeErrorResult(Exceptions.CODE_ERROR_FILE, "文件太大啦！请选择更小一些的文件重试！");
            } else if (t instanceof UnexpectedTypeException) {
                return makeErrorResult(Exceptions.CODE_ERROR_PARAMETER, "类型错误！");
            } else if (t instanceof InvocationTargetException) {
                InvocationTargetException e = (InvocationTargetException) t;
                return makeErrorResult(e.getTargetException());
            } else if (t instanceof UndeclaredThrowableException) {
                Throwable be = ((UndeclaredThrowableException) t).getUndeclaredThrowable();
                return makeErrorResult(be);
            }
        }
        return makeErrorResult(Exceptions.CODE_ERROR_UNKNOW, "未知错误");
    }

    public static Result<Object> makeErrorResult(String code, String message) {
        return new Result<Object>(code, message);
    }

    public static Map<String, Object> makeErrorMap(Throwable t) {
        if (t != null) {
            if (t.getClass().equals(BaseException.class)) {
                BaseException be = (BaseException) t;
                return makeErrorMap(be.getCode(), be.getMessage());
            } else if (t.getClass().equals(BaseRuntimeException.class)) {
                BaseRuntimeException be = (BaseRuntimeException) t;
                return makeErrorMap(be.getCode(), be.getMessage());
            } else if (t instanceof DeApiException) {
                DeApiException be = (DeApiException) t;
                return makeErrorMap(be.getCode(), be.getMessage());
            } else if (t instanceof MaxUploadSizeExceededException) {
                return makeErrorMap(Exceptions.CODE_ERROR_FILE, "文件太大啦！请选择更小一些的文件重试！");
            } else if (t instanceof UnexpectedTypeException) {
                return makeErrorMap(Exceptions.CODE_ERROR_PARAMETER, "类型错误！");
            } else if (t instanceof InvocationTargetException) {
                InvocationTargetException e = (InvocationTargetException) t;
                return makeErrorMap(e.getTargetException());
            } else if (t instanceof UndeclaredThrowableException) {
                Throwable be = ((UndeclaredThrowableException) t).getUndeclaredThrowable();
                return makeErrorMap(be);
            }
        }
        return makeErrorMap(Exceptions.CODE_ERROR_UNKNOW, "未知错误，请联系管理员。");
    }

    public static Map<String, Object> makeErrorMap(String code, String message) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("code", code);
        result.put("message", message);
        return result;
    }

    public static void assertNotNull(Object parameter, String parameterName) {
        if (parameter == null) {
            throw new BizException(Exceptions.CODE_ERROR_PARAMETER, String.format("参数[%s]不能为空!", parameterName));
        }
    }

    public static void assertNotEmpty(String parameter, String parameterName) {
        if (Strings.isBlank(parameter)) {
            throw new BizException(Exceptions.CODE_ERROR_PARAMETER, String.format("参数[%s]不能为空!", parameterName));
        }
    }

    public static void assertNotEmpty(Object[] objArray, String objArrayName) {
        if (ObjectUtils.isEmpty(objArray)) {
            throw new BizException(Exceptions.CODE_ERROR_PARAMETER, String.format("参数[%s]不能为空!", objArrayName));
        }
    }

    public static void assertNotEmpty(Collection<?> collection, String collectionName) {
        if (CollectionUtils.isEmpty(collection)) {
            throw new BizException(Exceptions.CODE_ERROR_PARAMETER, String.format("参数[%s]不能为空!", collectionName));
        }
    }

    public static ErrorFaceResponse wrapLacErrorResponse(Throwable t) {
        if (t != null) {
            if (t instanceof BaseException) {
                BaseException be = (BaseException) t;
                return new ErrorFaceResponse(be.getCode(), be.getMessage());
            } else if (t instanceof BaseRuntimeException) {
                BaseRuntimeException be = (BaseRuntimeException) t;
                return new ErrorFaceResponse(be.getCode(), be.getMessage());
            } else if (t instanceof DeApiException) {
                DeApiException be = (DeApiException) t;
                return new ErrorFaceResponse(be.getCode(), be.getMessage());
            } else if (t instanceof MaxUploadSizeExceededException) {
                return new ErrorFaceResponse(Exceptions.CODE_ERROR_FILE, "文件太大啦！请选择更小一些的文件重试！");
            } else if (t instanceof UnexpectedTypeException) {
                return new ErrorFaceResponse(Exceptions.CODE_ERROR_PARAMETER, "类型错误！");
            } else if (t instanceof UndeclaredThrowableException) {
                Throwable be = ((UndeclaredThrowableException) t).getUndeclaredThrowable();
                return wrapLacErrorResponse(be);
            } else if (t instanceof InvocationTargetException) {
                InvocationTargetException e = (InvocationTargetException) t;
                return wrapLacErrorResponse(e.getTargetException());
            }
        }
        return new ErrorFaceResponse(Exceptions.CODE_ERROR_UNKNOW, "未知错误");
    }

}
